package com.cskaoyan.service;

import com.cskaoyan.bean.po.MarketSystem;
import com.cskaoyan.bean.po.MarketSystemExample;
import com.cskaoyan.bean.vo.ExpressConfigVO;
import com.cskaoyan.bean.vo.MallConfigVO;
import com.cskaoyan.bean.vo.OrderConfigVO;
import com.cskaoyan.bean.vo.WxConfigVO;
import com.cskaoyan.mapper.MarketSystemMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @Auther: Yang Yi-zhou
 * @Date: 2022/9/7 14:21
 * @Description:
 */
@Service
public class ConfigServiceImpl implements ConfigService {
    @Autowired
    MarketSystemMapper marketSystemMapper;

    @SneakyThrows
    @Override
    public MallConfigVO getMallConfig() {
        Class<MallConfigVO> mallConfigVOClass = MallConfigVO.class;
        MallConfigVO mallConfigVO = mallConfigVOClass.newInstance();
        Field[] declaredFields = mallConfigVOClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            String declaredFieldName = declaredField.getName();
            MarketSystemExample example = new MarketSystemExample();
            MarketSystemExample.Criteria criteria = example.createCriteria();
            criteria.andKeyNameEqualTo(declaredFieldName);
            List<MarketSystem> marketSystems = marketSystemMapper.selectByExample(example);
            String keyValue = marketSystems.get(0).getKeyValue();
            declaredField.setAccessible(true);
            declaredField.set(mallConfigVO, keyValue);
        }
        return mallConfigVO;
    }

    @SneakyThrows
    private <T> T getConfig(Class<T> clazz) {
        T instance = clazz.newInstance();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            String declaredFieldName = declaredField.getName();
            MarketSystemExample example = new MarketSystemExample();
            MarketSystemExample.Criteria criteria = example.createCriteria();
            criteria.andKeyNameEqualTo(declaredFieldName);
            List<MarketSystem> marketSystems = marketSystemMapper.selectByExample(example);
            String keyValue = marketSystems.get(0).getKeyValue();
            declaredField.setAccessible(true);
            declaredField.set(instance, keyValue);
        }
        return instance;
    }

    @SneakyThrows
    private <T> Boolean updateConfig(T t) {

        Class clazz = t.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        int rows = 0;
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Object value = declaredField.get(t);
            String fieldName = declaredField.getName();
            MarketSystem record = new MarketSystem();
            record.setKeyValue((String) value);
            MarketSystemExample example = new MarketSystemExample();
            example.createCriteria().andKeyNameEqualTo(fieldName);
            rows += marketSystemMapper.updateByExampleSelective(record, example);
        }
        return rows > 0 ? true : false;
    }


    @SneakyThrows
    @Override
    public Boolean updateMallConfig(MallConfigVO mallConfigVO) {
        Class<MallConfigVO> mallConfigVOClass = MallConfigVO.class;
        Field[] declaredFields = mallConfigVOClass.getDeclaredFields();
        int rows = 0;
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Object value = declaredField.get(mallConfigVO);
            String fieldName = declaredField.getName();
            MarketSystem record = new MarketSystem();
            record.setKeyValue((String) value);
            MarketSystemExample example = new MarketSystemExample();
            example.createCriteria().andKeyNameEqualTo(fieldName);
            rows += marketSystemMapper.updateByExampleSelective(record, example);
        }
        return rows > 0 ? true : false;
    }

    @Override
    public ExpressConfigVO getExpressConfig() {
        return getConfig(ExpressConfigVO.class);
    }

    @Override
    public boolean updateExpressConfig(ExpressConfigVO expressConfigVO) {
        return updateConfig(expressConfigVO);
    }

    @Override
    public OrderConfigVO getOrderConfig() {
        return getConfig(OrderConfigVO.class);
    }

    @Override
    public boolean updateOrderConfig(OrderConfigVO orderConfigVO) {
        return updateConfig(orderConfigVO);
    }

    @Override
    public WxConfigVO getWxConfig() {
        return getConfig(WxConfigVO.class);
    }

    @Override
    public boolean updateWxConfig(WxConfigVO wxConfigVO) {
        return updateConfig(wxConfigVO);
    }
}
